<?php
// +----------------------------------------------------------------------
// |MCPHP[基于ThinkPHP6.1开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2023 http://www.mingchangruanjian.com
// +----------------------------------------------------------------------
// | Author jokerfei [ jokerfei377@gmail.com ]
// +----------------------------------------------------------------------
// | 铭畅软件 技术部 出品
// +----------------------------------------------------------------------
namespace addons\WeChat\controller;

require_once __DIR__ . '/../sdk/include.php';

/**
 * Class AppPay 微信开放平台支付联调
 * @package plugins\WeChat\controller
 * @Author jokerfei [ jokerfei377@gmail.com ]
 * @created 2019/9/9 22:07
 */
class MiniPay extends Base
{

    public $mini_config;

    /**
     * 返回实例本身
     * MiniPay constructor.
     * @param null $config
     */
    public function __construct($config = null)
    {
        parent::__construct();
        if (is_array($config)) {
            $this->config = array_merge($this->config, $config);
        }

        $this->mini_config = [
            'appid'      => $this->config['mini_appid'],
            'appsecret'  => $this->config['mini_appsecret'],
            // 配置商户支付参数（可选，在使用支付功能时需要）
            'mch_id'     => $this->config['mchid'],
            'mch_key'    => $this->config['key'],
            // 配置商户支付双向证书目录（可选，在使用退款|打款|红包时需要）
            'ssl_key'    => $this->config['sslkey_path'],
            'ssl_cer'    => $this->config['sslcert_path'],
            // 缓存目录配置（可选，需拥有读写权限）
            'cache_path' => '',
        ];
    }

    /**
     * 创建支付一个订单
     * @param $data
     * @Author jokerfei [ jokerfei377@gmail.com ]
     * @created 2020/2/19 16:41
     */
    public function pay($data)
    {
        $body         = $data['body'];
        $total_fee    = $data['total_fee'];
        $out_trade_no = $data['out_trade_no'];
        //组装订单数据
        $body = preg_replace('/\r\n/', '', $body);
        $body = mb_strlen($body) > 40 ? mb_substr($body, 0, 40, 'utf-8') . '...' : $body;

        $time = time();

        // 创建接口实例
        $wechat = new \WeChat\Pay($this->mini_config);

        // 组装参数，可以参考官方商户文档
        $options = [
            'body'             => $body,
            'total_fee'        => $total_fee * 100,
            'out_trade_no'     => $out_trade_no,
            'openid'           => $data['xcx_openid'],
            'trade_type'       => 'JSAPI',
            'notify_url'       => sysconfig('site', 'site_domain') . '/notify/wechat/mini',
        ];
        // 创建订单
        $result = $wechat->createOrder($options);

        if ($result['return_code'] != 'SUCCESS') {
            throw new \Exception($result['return_msg']);
        }
        if ($result['result_code'] != 'SUCCESS') {
            throw new \Exception($result['err_code_des']);
        }
        // 返回数据
        $order = new \WePay\Order($this->mini_config);
        $pay   = $order->jsapiParams($result['prepay_id']);
        return $pay;
    }

    /**
     * 查询订单
     * @Author jokerfei [ jokerfei377@gmail.com ]
     * @created 2020/2/19 16:43
     */
    public function queryOrder($transaction_id, $out_trade_no)
    {
        try {
            // 创建接口实例
            $wechat = new \WeChat\Pay($this->mini_config);

            // 组装参数，可以参考官方商户文档
            $options = [
                'transaction_id' => $transaction_id,
                'out_trade_no'   => $out_trade_no,
            ];

            // 尝试创建订单
            $result = $wechat->queryOrder($options);

            // 订单数据处理
            return $result;

        } catch (\Exception $e) {

            // 出错啦，处理下吧
            echo $e->getMessage() . PHP_EOL;

        }
    }

    /**
     * 退款
     * @Author jokerfei [ jokerfei377@gmail.com ]
     * @created 2020/2/19 16:41
     */
    public function backPay($data)
    {
        $total_fee    = floatval($data['total_fee']);
        $refund_fee   = floatval($data['refund_fee']);
        $out_trade_no = $data['out_trade_no'];
        $time    = time();
        $wechat  = new \WeChat\Pay($this->mini_config);
        $options = [
            'total_fee'     => $total_fee * 100, //订单总金额
            'out_refund_no' => $data['server_no'],
            'out_trade_no'  => $out_trade_no, //商户订单号
            'refund_fee'    => $refund_fee * 100, //退款金额
            'refund_desc'   => $data['refund_reason'], //退款理由
            'notify_url'    => sysconfig('site', 'site_domain') . '/notify/wechat/minipayBack',
        ];
        // 创建退款订单
        $result = $wechat->createRefund('jsapi', $options);
        if ($result['return_code'] == 'FAIL') {
            throw new \Exception($result['return_msg']);
        }
        if ($result['result_code'] == 'FAIL') {
            throw new \Exception($result['err_code'] . ':' . $result['err_code_des']);
        }
        return $result;
    }

    /**
     * 商户转账到零钱V3
     * @param type $openid
     * @param type $money
     * @param type $true_name
     * @return type
     */
    public function transfersV3($openid, $amount, $partner_trade_no, $re_user_name, $desc)
    {

        $wechat = new \WePayV3\Transfers($this->mini_config);
        //throw new InvalidResponseException
        $result = $wechat->batchs([
            "out_batch_no"         => "p" . $partner_trade_no,
            "batch_name"           => $desc,
            "batch_remark"         => $desc,
            "total_amount"         => bcmul($amount, 100, 0),
            "total_num"            => 1,
            "transfer_detail_list" => [
                [
                    "out_detail_no"   => $partner_trade_no,
                    "transfer_amount" => bcmul($amount, 100, 0),
                    "transfer_remark" => $desc,
                    "openid"          => $openid,
                    "user_name"       => $re_user_name,
                ],
            ],
        ]);
        return $result;
    }

    //退款状态查询
    public function bcakQueryPay($out_refund_no)
    {

    }

    //同步回调
    public function verifyReturn($out_trade_no)
    {

    }

    //异步回调
    public function initWechatPay()
    {
        // 创建接口实例
        $wechat = new \WeChat\Pay($this->mini_config);

        // 订单数据处理
        return $wechat;
    }
}
